﻿/* 版本记录
 * 
 * */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using GKQC.Common;
using GKQC.DbHelper.DbModels;
using GKQC.DbHelper.ViewModels;
using TestLeakApp;
using System.Diagnostics;
using System.Linq;
using GKQC.Language;

namespace GKQC.Machine
{
    /// <summary>
    /// 機型LCR11022, 用來檢測CAP、DF、ESR、高頻阻抗
    /// </summary>
    public partial class Form1601_20 : QcFormBase, IMachine
    {
        #region 私有变量
        private bool isMonitor = false; //是否监听
        private bool isListening = false;
        bool isTestting = false;
        int _CurrentRowIndex = 0;
        /// <summary>
        /// 是否全自動測試：非全自動測試只測試LC ,不用LCR儀器
        /// </summary>
        bool IsAllAuto { get; set; }
        OffsetCompute1601 _OffsetCompute;  

        public List<ElectricViewModel> ElectricViewModels { get; set; }
        UserModel _User; 

        Form parentForm;
        public bool IsClosing { get; set; }

        Settings.LcrType _lcrType = Settings.LcrType.SX10091A;
        Settings.LcType _lcType = Settings.LcType.CH2311;
        //string _LcrType = "LCR11022";
        ILcrMeter lcrMeter = null;
        ILcMeter lcMeter = null;
        ILcMeter lcMeter2 = null;
        BOX20 _Box = null;
        BOX20 _Box2 = null;
        StringBuilder sbComMessage = new StringBuilder();
        FormMutilMsgBox formMutilMsgBox = null;
        BackgroundWorker _TestWorker;
        TestParams _TestParams;
        TestStatus _TestStatus;
        public StandardView FirstStandardView { get; set; }
        public StandardView SecondStandardView { get; set; }
        ReportSetModel _Report;
        /// <summary>
        /// 第一个批次的测试次数
        /// </summary>
        public int FirstSNo { get; set; } = 1;
        /// <summary>
        /// 第二个批次的测试次数
        /// </summary>
        public int SecondSNo { get; set; } = 1;

        /// <summary>
        /// 第一个批次的测试次数
        /// </summary>
        public double FirstCapRate { get; set; } = 20;
        /// <summary>
        /// 第二个批次的测试次数
        /// </summary>
        public double SecondCapRate { get; set; } = 20;

        /// <summary>
        /// 第1个测试批次的第一次测试记录,用于计算试验后CAP是否合格
        /// </summary>
        public OrtDtlModel FirstDtl_MinSNo { get; set; }
        /// <summary>
        /// 第2个测试批次的第一次测试记录,用于计算试验后CAP是否合格
        /// </summary>
        public OrtDtlModel SecondDtl_MinSNo { get; set; }

        public void SetFirstLotBackgroup()
        {
            try
            {
                if (IsDoubleTest)
                {
                    if (this.ElectricViewModels.Count > 1)
                    {
                        int count = this.ElectricViewModels.Where(t => t.HeadId == this.ElectricViewModels[0].HeadId).Count();
                        if (count > 0)
                        {
                            for (int i = 0; i < count; i++)
                            {
                                if (i >= this.Grid.Rows.Count) break;
                                this.Grid.Rows[i].DefaultCellStyle.BackColor = Color.Red;
                            }
                        }
                    }
                }
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        #endregion

        #region 构造函数
        public Form1601_20(Form parentForm, UserModel user, double voltage
            , List<ElectricViewModel> electricViewModels
            , StandardView standardView
            , ReportSetModel report)
        {
            try
            {
                InitializeComponent();

                this._Report = report;
                //grid 显示行号
                this.Grid.Dock = DockStyle.Fill;
                this.Grid.AutoGenerateColumns = false;
                this.Grid.CellFormatting +=
                     new System.Windows.Forms.DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormatting);
                this.Grid.CellFormatting +=
                     new DataGridViewCellFormattingEventHandler(DataGridViewSet.CellFormattingForColor);
                this.parentForm = parentForm;
                this.ElectricViewModels = electricViewModels;
                Grid.DataSource = new BindingList<ElectricViewModel>(this.ElectricViewModels);
                this.FirstStandardView = standardView;
                txtVoltage.Text = voltage.ToString();
                this._User = user;
                IsAllAuto = Settings.IsAllAuto();
                _TestParams = new TestParams();
                _TestParams.LcLevel = "199e-6";
                _TestParams.Qty = TestParams.MaxQty;
                _TestParams.CDFreq = "0.12KHZ";
                _TestParams.ZRFreq = "100KHZ";
                _TestParams.TestItem = "CD-ZR-LC";
                _TestParams.LcVoltage = Convert.ToDecimal(voltage);
                _TestStatus = TestStatus.停止;
                _OffsetCompute = new OffsetCompute1601();
                if (this.ElectricViewModels.Count > 0 && this.ElectricViewModels.Count < _OffsetCompute.GetChannelCount())
                    _TestParams.Qty = this.ElectricViewModels.Count;
                else
                    _TestParams.Qty = _OffsetCompute.GetChannelCount();
                TestParams.MaxQty = _OffsetCompute.GetChannelCount();
                //numQty.Maximum = TestParams.MaxQty;

                getPortBuad();
                _lcrType = Settings.GetLcrType();
                _lcType = Settings.GetLcType();
                _Box = new BOX20(spBox, 1, new BOX20.MyComDelegate(ShowBoxResponseData),
                    new BOX20.ShowSendDataDel(ShowBoxResponseData));
                _Box2 = new BOX20(spBox, 2, new BOX20.MyComDelegate(ShowBoxResponseData),
                    new BOX20.ShowSendDataDel(ShowBoxResponseData));
                lcrMeter = MachineFactory.GetLcrMeter();
                lcMeter = new LcMeter1601();
                lcMeter2 = new LcMeter1601_20();

                BindingControls();
                
                InitCombo();
                
                //#if DEBUG
                //                lcrMeter = new LcrMeterDebug();
                //#endif
                btnMonitor_Click(null, null);
                btSet_Click(null, null);

                _TestWorker = new BackgroundWorker();
                _TestWorker.WorkerSupportsCancellation = true;
                _TestWorker.WorkerReportsProgress = true;
                _TestWorker.ProgressChanged += TestWorker_ProgressChanged;
                _TestWorker.DoWork += TestWorker_DoWork;
                _TestWorker.RunWorkerCompleted += TestWorker_RunWorkerCompleted;

                int channelcount = _OffsetCompute.GetChannelCount();
                if (this.ElectricViewModels.Count > 0 
                    && this.ElectricViewModels.Count < channelcount)
                {
                    numQty.Value = electricViewModels.Count;
                    _TestParams.Qty = electricViewModels.Count;
                }
                else
                {
                    numQty.Value = channelcount;
                    _TestParams.Qty = channelcount;
                }

                DisCharge();

                spLcr.DataReceived += SpLcr_DataReceived;

                SetStardardInGridHeadText();

                LanguageHelper.SetControlLanguageText(this);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                QMessageBox.Show(ex.Message,"異常S0034", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        void SetStardardInGridHeadText()
        {
            try
            {
                if(FirstStandardView != null)
                {
                    if (FirstStandardView.CapMax > 0)
                        ColCap.HeaderText =
                        ColCap.HeaderText + Environment.NewLine +
                        FirstStandardView.CapMin + "~" + FirstStandardView.CapMax;

                    if (FirstStandardView.DfMax > 0)
                        ColDf.HeaderText =
                        ColDf.HeaderText + Environment.NewLine +
                        "≤" + FirstStandardView.DfMax;

                    if (FirstStandardView.EsrMax > 0)
                        ColEsr.HeaderText =
                        ColEsr.HeaderText + Environment.NewLine +
                        "≤" + FirstStandardView.EsrMax;

                    if (FirstStandardView.ZMax > 0)
                        ColZ.HeaderText =
                        ColZ.HeaderText + Environment.NewLine +
                        "≤" + FirstStandardView.ZMax;

                    if (FirstStandardView.LcMax > 0)
                        ColLc.HeaderText =
                        ColLc.HeaderText + Environment.NewLine +
                        "≤" + FirstStandardView.LcMax;
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }  
        }

        private void ShowBoxResponseData(byte[] received, int len)
        {
            Action<string> method = delegate (string sss) {
                sbComMessage.AppendLine(sss);
            };
            string text = string.Empty;
            for (int i = 0; i < len; i++)
            {
                text = text + received[i].ToString("X2") + " ";
            }
            text = text + Environment.NewLine;
            if (base.InvokeRequired)
            {
                base.BeginInvoke(method, new object[] { text });
            }
            else
            {
                sbComMessage.AppendLine(text);
            }
        }

        private void ShowMachineResponse(string text)
        {
            Action<string> method = delegate (string sss) {
                sbComMessage.AppendLine(sss);
            };
            if (base.InvokeRequired)
            {
                base.BeginInvoke(method, new object[] { text });
            }
            else
            {
                sbComMessage.AppendLine(text);
            }
        }

        int count = 0;

        bool IsValid(ItemCode itemCode, double value, ElectricViewModel model)
        {
            if (model == null) return true;

            StandardView standView;
            OrtDtlModel minDtl;
            int sno = 0;
            double CapRate = 20;
            int capIndex = 0;

            if(this.IsDoubleTest)
            {
                capIndex = ElectricViewModels.IndexOf(model);
                if (capIndex < ElectricViewModels.Count/2)
                {
                    //第一批次
                    standView = FirstStandardView;
                    minDtl = FirstDtl_MinSNo;
                    sno = FirstSNo;
                    CapRate = FirstCapRate;
                }
                else
                {
                    //第二批次
                    capIndex = capIndex - ElectricViewModels.Count / 2;
                    standView = SecondStandardView;
                    minDtl = SecondDtl_MinSNo;
                    sno = SecondSNo;
                    CapRate = SecondCapRate;
                }
            }
            else
            {
                standView = FirstStandardView;
                minDtl = FirstDtl_MinSNo;
                sno = FirstSNo;
            }

            if(sno <=1 || itemCode != ItemCode.CAP)
            {
                return standView.IsValid(itemCode, value);
            }
            else
            {
                if (minDtl.ElectricViewModels.Count < capIndex + 1)
                    return true;
                else
                {
                    return (value >= minDtl.ElectricViewModels[capIndex].CAP * (1 - CapRate)
                        && value <= minDtl.ElectricViewModels[capIndex].CAP * (1 + CapRate)
                        );
                }
            }
        }

        string[] newlines = new string[] { "\r\n" };
        string newline = "\r\n" ;
        string dateformat = " AAA:mm:ss:fff: ";
        char[] dotchars = new char[] { ',' };
        string zero = "0";
        private void SpLcr_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                Thread.Sleep(50);
                string rawString = lcrMeter.GetData(spLcr);
                sbComMessage.AppendFormat(count.ToString() + DateTime.Now.ToString(dateformat) 
                    + rawString + newline);
                if (rawString == lcrRawData) return;
                strData = rawString.ToLower();
                string[] a = strData.Split(newlines, StringSplitOptions.None);
                string strData2 = string.Empty;
                for (int i = a.Length - 1; i >= 0; i--)
                {
                    if (!string.IsNullOrWhiteSpace(a[i]))
                    {
                        strData2 = a[i];
                        string[] dataArrTemp = strData2.Split(dotchars, StringSplitOptions.RemoveEmptyEntries);
                        if (dataArrTemp.Length == 5 && dataArrTemp[dataArrTemp.Length - 1] == zero)
                        {
                            count++;
                            lcrRawData = rawString;
                            break;
                        }
                    }
                }
            }
            catch
            {
                lcrRawData = string.Empty;
            }
        }

        private void TestWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                timerLc.Enabled = false;
                timerLcr.Enabled = false;
                timerLc10.Enabled = false;
                timerStatus.Enabled = false;

                //Logger.LogMessage(sbComMessage.ToString());

                if (e.Error != null)
                {
                    if (_TestStatus == TestStatus.充電中 || _TestStatus == TestStatus.LC測試中)
                    {
                        stopwatch.Restart();
                        _Box.DischargeAll();
                        Thread.Sleep(100);
                        lcMeter.DisCharge(spLc);
                    }

                    if (e.Error != null && e.Error.Message == "1000")
                    {
                        sbComMessage.AppendLine("LC值超出量程！");
                        QMessageBox.Show("LC值超出量程！", "LC档位错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else if (e.Error != null && e.Error.Message == "2000")
                    {
                        //短路或电压下降
                        sbComMessage.AppendLine("LC充电时电压下降或充不上去，请检查电容器是否插反了!");
                        QMessageBox.Show("LC充电时电压下降或充不上去，请检查电容器是否短路或插反了!", "LC充电错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else if (e.Error != null && e.Error.Message == "3000")
                    {
                        sbComMessage.AppendLine("LC充电时电压下降或充不上去，请检查电容器是否插反了!");
                        QMessageBox.Show("LC充电时电压下降或充不上去，请检查电容器是否插反了！" +
                            Environment.NewLine + "最大电压值：" + _TestParams.MaxTestVoltage
                            , "LC充电异常"
                            , MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        sbComMessage.AppendLine("测试时发生异常：" + e.Error.Message);
                        QMessageBox.ShowException(e.Error);
                    }
                }
                else if(!e.Cancelled)
                {
                    try
                    {
                        if (this.Grid.Rows.Count > (_CurrentRowIndex + _TestParams.Qty))
                            _CurrentRowIndex += _TestParams.Qty;
                        else
                            _CurrentRowIndex = 0;
                        this.Grid.ClearSelection();
                        this.Grid.Rows[_CurrentRowIndex].Cells[Grid.CurrentCell.ColumnIndex].Selected = true;
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex);
                    }
                }

                DisCharge();

                this.Grid.Refresh();
                lblStatus.Text = "待机";
                _TestStatus = TestStatus.停止;
                isTestting = false;
                SetControlsEnable(true);
            }
            catch(Exception ex)
            {
                DisCharge();
                Logger.LogError(ex);
            }
            finally
            {
                isTestting = false;
            }
        }

        private void TestWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                if (_TestStatus == TestStatus.LCR測試中)
                {
                    sbComMessage.AppendLine("LCR測試中");
                    timerStatus.Enabled = false;
                    timerLcr.Enabled = true;
                }
                if (_TestStatus == TestStatus.LCR測試完成)
                {
                    sbComMessage.AppendLine("LCR測試完成");
                    timerLcr.Enabled = false;
                }
                else if (_TestStatus == TestStatus.充電中)
                {
                    sbComMessage.AppendLine("充電中");
                    //timerStatus.Enabled = true;
                }
                else if(_TestStatus == TestStatus.LC測試中)
                {
                    sbComMessage.AppendLine("LC測試中");
                    timerStatus.Enabled = false;
                    timerLc.Enabled = true;
                    timerLc10.Enabled = true;
                }
                else if (_TestStatus == TestStatus.LC測試完成)
                {
                    sbComMessage.AppendLine("LC測試完成");
                    timerLc10.Enabled = false;
                }
                else if (_TestStatus == TestStatus.放電中)
                {
                    sbComMessage.AppendLine("放電中");
                    //timerStatus.Enabled = true;
                }

                string tdelay = string.Empty;
                if(_TestStatus == TestStatus.充電中 || _TestStatus == TestStatus.放電中)
                {
                    int delay = (_TestStatus == TestStatus.充電中 ? _TestParams.LcChargeTime : _TestParams.LcDischargeTime)
                        - (int)stopwatch.Elapsed.TotalSeconds;
                    if (delay >0) tdelay = delay.ToString();
                }

                UpdateStatusLabel(tdelay +Enum.GetName(_TestStatus.GetType(), _TestStatus));
                //Grid.DataSource = new BindingList<ElectricViewModel>(ElectricViewModels);
                Grid.Refresh();
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        Stopwatch stopwatch = new Stopwatch();
        string rawStringFormat = "通道:{0},次数:{1}, 原始数据:{2}";
        string beforeStringFormat = "計算前cap.{0}, df.{1}, x.{2}, r.{3}";
        string afterStringFormat = "計算後cap.{0}, df.{1}, z.{2}, r.{3}";
        string lcrStartFormat = "\r\nLCR測量通道數：{0}/{1} 开始";
        string lcrRawData = string.Empty;

        private void TestWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            sbComMessage.Length = 0;
            int lcFirstDelay = _OffsetCompute.GetLcFirstDelay();
            int lcrFirstDelay = _OffsetCompute.GetLcrFirstDelay();
            int testTimes = _OffsetCompute.GetTestTimes();
            int lcrRowIndex = _CurrentRowIndex;
            int testCount = 0;
            int testQty = (int)numQty.Value;
            int box20time = (int)(_OffsetCompute.GetBox20Time() * 1000m);
            if (box20time < 500) box20time = 500;

            #region LCR
            if (_TestParams.TestItem != "LC" && !_TestParams.IsLC2 && !_TestParams.IsLcOnly)
            {
                DisCharge();
                Thread.Sleep(100);

                _TestStatus = TestStatus.LCR參數設置;
                _TestWorker.ReportProgress(1);
                lcrMeter.SetFreq(spLcr, _TestParams.CDFreq, _TestParams.ZRFreq, _TestParams.TestItem);
                _Box.InitialAll();
                Thread.Sleep(box20time);
                try { _Box2.InitialAll(); }catch(Exception ex) { Logger.LogError(ex); }
                Thread.Sleep(500);
                _Box.SwitchToLCR();
                Thread.Sleep(200);
                _TestStatus = TestStatus.LCR測試中;
                _TestWorker.ReportProgress(2);

                for (int i = 1; i <= testQty; i++)
                {
                    //"\r\nLCR測量通道數：{0}/{1} 开始";
                    sbComMessage.AppendFormat(lcrStartFormat, i.ToString() ,testQty.ToString());
                    if (_TestWorker.CancellationPending) break;
                    if (i < 11)
                    {
                        if (i == 0) try { _Box2.InitialAll();Thread.Sleep(1500); }catch (Exception ex) { Logger.LogError(ex); }
                        _Box.LCRTestChannel((byte)i, true);
                    }
                    else
                    {
                        if (i == 11)
                        {
                            _Box.InitialAll();
                            Thread.Sleep(box20time);
                            try { _Box2.SwitchToLCR(); } catch (Exception ex) { Logger.LogError(ex); }
                            Thread.Sleep(500);
                        }
                        _Box2.LCRTestChannel((byte)(i - 10), true);
                    }

                    if (i == 1 && i==11)
                    {
                        Thread.Sleep(lcrFirstDelay * 1000);
                    }
                    Thread.Sleep(_TestParams.LcrTestDelay * 1000);

                    decimal cap, df, x, r, z;
                    cap = df = x = r = z = 0;

                    testCount = 0;
                    for (int j = 0; j < testTimes; j++)
                    {
                        //sbComMessage.AppendLine("LCR測量次數：" + (j+1).ToString() + "/" + testTimes.ToString());
                        testCount++;
                        if (testCount > 30) break;

                        if (_TestWorker.CancellationPending)
                        {
                            if (i < 11)
                                _Box.LCRTestChannel((byte)i, false);
                            else
                            {
                                _Box2.LCRTestChannel((byte)(i - 10), false);
                            }
                            return;
                        }
                        lcrMeter.Fetch(spLcr, _TestParams.TestItem);
                        Thread.Sleep(460);
                        //string data = lcrMeter.GetData(spLcr);

                        //"通道:{0},次数:{1}, 原始数据:{2}"
                        //sbComMessage.AppendLine(string.Format(rawStringFormat, i.ToString(), j.ToString(), data));
                        sbComMessage.AppendLine(string.Format(rawStringFormat, i.ToString(), j.ToString(), lcrRawData));

                        if (lcrMeter.AnalysisData(lcrRawData, out cap, out df, out x, out r, _TestParams.TestItem, _TestParams.ZRFreq, true))
                        {
                            //"計算前cap.{0}, df.{1}, x.{2}, r.{3}"
                            sbComMessage.AppendLine(string.Format(beforeStringFormat, cap.ToString(), df.ToString(), x.ToString(), r.ToString()));
                            decimal rTemp = 0m;
                            decimal zTemp = 0m;
                            decimal xTemp = 0m;
                            _OffsetCompute.ComputeZR(r, x, _TestParams.ZRFreq, i, out rTemp, out zTemp, out xTemp);
                            r = rTemp;
                            z = zTemp;

                            //偏移量
                            z = z - Convert.ToDecimal(_OffsetCompute.GetZOffset());
                            r = r - Convert.ToDecimal(_OffsetCompute.GetROffset());

                            if (_TestParams.IsZ2 || _TestParams.IsEsr2)
                            {
                                if (_TestParams.TestItem.Contains("Z") && z != 0
                                    )
                                {
                                    ElectricViewModels[lcrRowIndex].Z2 = Math.Round(Convert.ToDouble(z * 1000), 4);
                                    ElectricViewModels[lcrRowIndex].Z2isValid =
                                        IsValid(ItemCode.Z2, ElectricViewModels[lcrRowIndex].Z2, ElectricViewModels[lcrRowIndex]);
                                        //FirstStandardView.IsValid(ItemCode.Z2, ElectricViewModels[lcrRowIndex].Z2);
                                }
                                if (_TestParams.TestItem.Contains("R") && r != 0
                                    )
                                {
                                    ElectricViewModels[lcrRowIndex].ESR2 = Math.Round(Convert.ToDouble(r * 1000), 4);
                                    ElectricViewModels[lcrRowIndex].ESR2isValid = 
                                        IsValid(ItemCode.ESR2, ElectricViewModels[lcrRowIndex].ESR2, ElectricViewModels[lcrRowIndex]);
                                    //FirstStandardView.IsValid(ItemCode.ESR2, ElectricViewModels[lcrRowIndex].ESR2);
                                }
                            }
                            else
                            {
                                if (_TestParams.TestItem.Contains("CD") && cap != 0
                                    )
                                {
                                    ElectricViewModels[lcrRowIndex].CAP = Math.Round(Convert.ToDouble(cap), 4);
                                    ElectricViewModels[lcrRowIndex].CAPisValid =
                                        IsValid(ItemCode.CAP, ElectricViewModels[lcrRowIndex].CAP, ElectricViewModels[lcrRowIndex]);
                                    //FirstStandardView.IsValid(ItemCode.CAP, ElectricViewModels[lcrRowIndex].CAP);
                                }
                                if (_TestParams.TestItem.Contains("CD") && df != 0
                                    )
                                {
                                    ElectricViewModels[lcrRowIndex].DF = Math.Round(Convert.ToDouble(df), 2);
                                    ElectricViewModels[lcrRowIndex].DFisValid =
                                        IsValid(ItemCode.DF, ElectricViewModels[lcrRowIndex].DF, ElectricViewModels[lcrRowIndex]);
                                    //FirstStandardView.IsValid(ItemCode.DF, ElectricViewModels[lcrRowIndex].DF);
                                }
                                if (_TestParams.TestItem.Contains("R") && r != 0
                                    )
                                {
                                    ElectricViewModels[lcrRowIndex].ESR = Math.Round(Convert.ToDouble(r * 1000), 4);
                                    ElectricViewModels[lcrRowIndex].ESRisValid =
                                        IsValid(ItemCode.ESR, ElectricViewModels[lcrRowIndex].ESR, ElectricViewModels[lcrRowIndex]);
                                    //FirstStandardView.IsValid(ItemCode.ESR, ElectricViewModels[lcrRowIndex].ESR);
                                }
                                if (_TestParams.TestItem.Contains("Z") && z != 0
                                    )
                                {
                                    ElectricViewModels[lcrRowIndex].Z = Math.Round(Convert.ToDouble(z * 1000), 4);
                                    ElectricViewModels[lcrRowIndex].ZisValid =
                                        IsValid(ItemCode.Z, ElectricViewModels[lcrRowIndex].Z, ElectricViewModels[lcrRowIndex]);
                                    //FirstStandardView.IsValid(ItemCode.Z, ElectricViewModels[lcrRowIndex].Z);
                                }
                            }

                            //"計算後cap.{0}, df.{1}, z.{2}, r.{3}"
                            sbComMessage.AppendLine(string.Format(
                                afterStringFormat
                                , cap.ToString(), df.ToString(), z.ToString(), r.ToString()));
                            sbComMessage.AppendLine(string.Empty);
                        }

                        _TestWorker.ReportProgress(2);
                        Thread.Sleep(50);
                    }

                    if (i < 11)
                        _Box.LCRTestChannel((byte)i, false);
                    else
                    {
                        _Box2.LCRTestChannel((byte)(i - 10), false);
                    }
                    Thread.Sleep(200);

                    lcrRowIndex++;
                    _TestWorker.ReportProgress(i + 2);
                    if (lcrRowIndex >= ElectricViewModels.Count) break;
                } //LCR通道循環

                _TestStatus = TestStatus.LCR測試完成;
                _TestWorker.ReportProgress(3);
                Thread.Sleep(300);
            }
            #endregion LCR

            #region LC测试
            try
            {
                if ((_TestParams.TestItem.Contains("LC") || _TestParams.IsLC2) && !_TestParams.IsZ2 && !_TestParams.IsLcrOnly
                    && !_TestWorker.CancellationPending)
                {
                    _TestStatus = TestStatus.LC參數設置;
                    _TestWorker.ReportProgress(20);
                    Thread.Sleep(100);
                    //BOX COM6 初始化盒子 0x01
                    _Box.InitialAll();
                    Thread.Sleep(box20time);
                    _Box2.InitialAll();
                    Thread.Sleep(box20time);
                    //LC1 COM5 控制仪器* rmt
                    lcMeter.ControlMachine(spLc);
                    Thread.Sleep(50);
                    lcMeter2.ControlMachine(spLc10);
                    //LC1 COM5 设定电压 prog:volt50.0
                    Thread.Sleep(150);
                    lcMeter.SetVoltage(spLc, _TestParams.LcVoltage);
                    Thread.Sleep(200);
                    decimal voltage = lcMeter.GetVoltage(spLc);
                    if(voltage >0)
                    sbComMessage.AppendLine("电压设置值:" + voltage.ToString());

                    //LC1 COM5 设定充电时间 prog:charge60
                    Thread.Sleep(200);
                    lcMeter.SetCharTime(spLc, _TestParams.LcChargeTime);
                    //Thread.Sleep(50);
                    //lcMeter.SetCharTime(spLc10, _TestParams.LcChargeTime);
                    //LC1 COM5 设定测试时间 prog: test100
                    Thread.Sleep(200);
                    lcMeter.SetTestTime(spLc, _TestParams.LcTesTime);
                    //Thread.Sleep(50);
                    //lcMeter.SetTestTime(spLc10, _TestParams.LcTesTime);
                    // LC1 COM5 设定放电时间 prog: disc5
                    Thread.Sleep(200);
                    lcMeter.SetDisChargeTime(spLc, _TestParams.LcDischargeTime);
                    //  LC2 COM3 设定漏电流档位 Prog: leak0.001
                    Thread.Sleep(50);
                    lcMeter2.SetLeak(spLc10, _TestParams.LcLevel);

                    _TestWorker.ReportProgress(21);

                    //BOX COM6 切换盒子至充电状态 0x02
                    Thread.Sleep(50);
                    _Box.ChargeAll();
                    Thread.Sleep(500);
                    _Box2.ChargeAll();
                    Thread.Sleep(500);
                    //LC1 COM5 充电 Charge
                    lcMeter.Char(spLc);
                    //充电倒计时
                    stopwatch.Restart();
                    _TestStatus = TestStatus.充電中;
                    _TestWorker.ReportProgress(22);
                    //sbComMessage.AppendLine(TestStatus.充電中.GetType().Name);

                    int overRangeCount = 0;
                    double currentVoltage = 0;
                    int voltageDownCount = 0;
                    double maxVoltage = 0;
                    double maxVoltage2 = 0;
                    int reverse = 0;

                    while (true)
                    {
                        if (_TestWorker.CancellationPending) break;
                        if (stopwatch.Elapsed.TotalSeconds >= _TestParams.LcChargeTime)
                            break;
                        Thread.Sleep(500);
                        double realVoltage = Convert.ToDouble(lcMeter.GetVoltage(spLc));
                        if(realVoltage > _TestParams.MaxTestVoltage)
                            _TestParams.MaxTestVoltage = realVoltage;
                        if (realVoltage > maxVoltage)
                        {
                            maxVoltage = realVoltage;
                            reverse = 0;
                        }
                        else if (realVoltage > 0) reverse++;

                        if(reverse>=3)
                        {
                            if (maxVoltage > maxVoltage2 + 1) reverse = 0;
                        }

                        //反向充电
                        if (reverse >= 5 && Convert.ToDecimal(maxVoltage) < _TestParams.LcVoltage - 2.2m
                            && Convert.ToDecimal(maxVoltage) < _TestParams.LcVoltage * 0.90m)
                        {
                            throw new Exception("3000"); //反向充电
                        }


                        //充电时电压在下降表示异常
                        if (currentVoltage > 0 && realVoltage < currentVoltage - 2
                            && Convert.ToDecimal(realVoltage) < _TestParams.LcVoltage * 0.90m)
                            voltageDownCount++;
                        if (voltageDownCount >= 3)
                            goto DISCHARGE;
                        if (realVoltage > 0 && realVoltage > currentVoltage) currentVoltage = realVoltage;

                        if (realVoltage > 1) ElectricViewModels.ForEach(m => m.RealVoltage = realVoltage);
                        _TestWorker.ReportProgress(22);
                        //"lc char voltage:"
                        sbComMessage.AppendLine(lcChargeVoltage + lcMeter.GetVoltage(spLc));
                        //Thread.Sleep(_TestParams.LcChargeTime * 1000);
                    }

                    //BOX COM6 切换盒子至测试状态 0x10
                    if (!_TestWorker.CancellationPending)
                    {
                        _Box.LCTestAll();
                        Thread.Sleep(500);
                        _Box2.LCTestAll();
                    }
                    Thread.Sleep(200);
                    if (!_TestWorker.CancellationPending) lcMeter.Test(spLc);
                    Thread.Sleep(50);
                    //lcMeter.Test(spLc10);
                    //測試延時
                    _TestStatus = TestStatus.LC測試中;
                    if (!_TestWorker.CancellationPending) Thread.Sleep(_TestParams.LcTestDelay * 1000);
                    _TestWorker.ReportProgress(22);

                    testCount = 0;


                    for (int j = 0; j < testTimes; j++)
                    {
                        //"\r\nLC測量次數：{0}/{1}"
                        sbComMessage.AppendFormat(lcTestTimes, j.ToString(), testTimes.ToString());
                        testCount++;
                        if (testCount > 30) break;
                        if (_TestWorker.CancellationPending) break;
                        if (j == 0) Thread.Sleep(_OffsetCompute.GetLcFirstDelay() * 1000);

                        double realVoltage = Convert.ToDouble(lcMeter.GetVoltage(spLc));
                        if (realVoltage > 1) ElectricViewModels.ForEach(m => m.RealVoltage = realVoltage);
                        //"lc test voltage:"
                        sbComMessage.AppendLine(lcTestVoltageFormat + lcMeter.GetVoltage(spLc));

                        string data = lcMeter2.GetLeak(spLc10,"1");
                        sbComMessage.AppendFormat(lcRawDataFormat + " 1-10： ", j.ToString(), data);
                        //Thread.Sleep(200); ;
                        //string data = lcMeter2.GetData(spLc10);
                        if (data.Contains("----")) overRangeCount++;
                        if (overRangeCount >= 3) goto DISCHARGE;
                        //"\r\nlc rawdata : times: {0} data: {1}"

                        //                        data = @"1:5.4923uA2:6.2430uA3:5.5763uA4:5.8918uA5:6.7040uA6:5.7527uA7:6.4567uA8:6.8519uA9:5.4401uA10:5.888uA
                        //1:0.0000uA2: 0.0048uA3: 0.0000uA4: 0.0000uA5: 0.0000uA6: 0.0061uA7: 0.0066uA8: 0.0069uA9: 0.0066uA10: 0.006uA";

                        List<double> lcList = lcMeter2.AnalysisData(data);

                        data = lcMeter2.GetLeak(spLc10, "2");
                        sbComMessage.AppendFormat(lcRawDataFormat + " 11-20： ", j.ToString(), data);
                        //Thread.Sleep(200); ;
                        //string data = lcMeter2.GetData(spLc10);
                        if (data.Contains("----")) overRangeCount++;
                        //if (overRangeCount >= 3) goto DISCHARGE;
                        //"\r\nlc rawdata : times: {0} data: {1}"

                        //                        data = @"1:5.4923uA2:6.2430uA3:5.5763uA4:5.8918uA5:6.7040uA6:5.7527uA7:6.4567uA8:6.8519uA9:5.4401uA10:5.888uA
                        //1:0.0000uA2: 0.0048uA3: 0.0000uA4: 0.0000uA5: 0.0000uA6: 0.0061uA7: 0.0066uA8: 0.0069uA9: 0.0066uA10: 0.006uA";

                        var lcList2 = lcMeter2.AnalysisData(data);
                        if (lcList2 != null && lcList2.Count > 0)
                            lcList.AddRange(lcList2);

                        sbComMessage.AppendLine(string.Format(lcDataFormat, j.ToString(), lcList.ToJson()));

                        for (int i = 0; i < lcList.Count; i++)
                        {
                            if (i >= testQty) break;
                            if (_TestWorker.CancellationPending) break;
                            if ((_CurrentRowIndex + i) >= ElectricViewModels.Count) break;
                            if (lcList[i] <= 0d) continue;
                            if (_TestParams.IsLC2) 
                            {
                                ElectricViewModels[_CurrentRowIndex + i].LC2 = lcList[i];
                                ElectricViewModels[_CurrentRowIndex + i].LC2isValid =
                                    IsValid(ItemCode.LC2, ElectricViewModels[_CurrentRowIndex + i].LC2, ElectricViewModels[_CurrentRowIndex + i]);
                                //FirstStandardView.IsValid(ItemCode.LC2, ElectricViewModels[_CurrentRowIndex + i].LC2);
                            }
                            else
                            {
                                ElectricViewModels[_CurrentRowIndex + i].LC = lcList[i];
                                ElectricViewModels[_CurrentRowIndex + i].LCisValid =
                                    IsValid(ItemCode.LC, ElectricViewModels[_CurrentRowIndex + i].LC, ElectricViewModels[_CurrentRowIndex + i]);
                                //FirstStandardView.IsValid(ItemCode.LC, ElectricViewModels[_CurrentRowIndex + i].LC);
                            }
                        }
                        //"lc times:{0}, data list:{1}"
                        
                        Thread.Sleep(300);
                        _TestWorker.ReportProgress(22);
                    }

                    _TestStatus = TestStatus.LC測試完成;
                    _TestWorker.ReportProgress(23);

                DISCHARGE:
                    Thread.Sleep(300);
                    _Box.DischargeAll();
                    Thread.Sleep(500);
                    _Box2.DischargeAll();
                    Thread.Sleep(500);
                    _TestStatus = TestStatus.放電中;
                    lcMeter.DisCharge(spLc);
                    stopwatch.Restart();
                    _TestWorker.ReportProgress(23);
                    //放电倒计时
                    int dischartTimeSecond = _TestParams.LcDischargeTime + 5;
                    double realVoltage1 = Convert.ToDouble(lcMeter.GetVoltage(spLc));
                    while (true)
                    {
                        double realVoltage = Convert.ToDouble(lcMeter.GetVoltage(spLc));
                        if (realVoltage >= 0) ElectricViewModels.ForEach(m => m.RealVoltage = realVoltage);
                        if (stopwatch.Elapsed.TotalSeconds > dischartTimeSecond && realVoltage < 2)
                        {
                            //ElectricViewModels.ForEach(m => m.RealVoltage = 0);
                            break;
                        }
                        else
                        {
                            if (stopwatch.Elapsed.TotalSeconds > 0
                                //&& stopwatch.Elapsed.TotalSeconds % 3 ==0
                                )
                                lcMeter.DisCharge(spLc);
                        }

                        if (realVoltage > 0) realVoltage1 = realVoltage;
                        if (stopwatch.Elapsed.TotalSeconds > 60) break;

                        //"lc discharge voltage: "
                        sbComMessage.AppendLine(lcdischargeFormat + realVoltage.ToString());
                        _TestWorker.ReportProgress(23);

                        Thread.Sleep(500);
                    }

                    ElectricViewModels.ForEach(m => m.RealVoltage = 0);
                    _TestWorker.ReportProgress(23);
                    //Thread.Sleep((_TestParams.LcDischargeTime + 3) * 1000);
                    //BOX COM6 初始化盒子 0x01
                    _Box.InitialAll();
                    Thread.Sleep(box20time);
                    _Box2.InitialAll();
                    Thread.Sleep(box20time);

                    //if (overRangeCount >= 3) throw new Exception("1000"); //LC超量程
                    if (voltageDownCount >= 3) throw new Exception("2000"); //短路或电压下降
                }
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
                sbComMessage.AppendLine(ex.Message);
                throw ex;
            }
            #endregion LC测试

            _TestStatus = TestStatus.停止;
            _TestWorker.ReportProgress(999);
        }
        
        string lcdischargeFormat = "LC放电电压: ";
        string lcDataFormat = "LC读取次数:{0}, 读取到的LC值:{1}";
        string lcRawDataFormat = "\r\nLC串口原始数据 : 次数: {0} 返回值: {1}";
        string lcTestVoltageFormat ="LC电压值:";
        string lcTestTimes = "\r\nLC測量次數：{0}/{1}";
        string lcChargeVoltage = "LC充电电压:";


        /// <summary>
        /// 测试前后的放电，防呆
        /// </summary>
        void DisCharge()
        {
            try
            {
                Stopwatch s = new Stopwatch();
                s.Start();
                Thread.Sleep(200);
                _Box.DischargeAll(); //切换盒子到放电状态
                _Box2.DischargeAll();
                Thread.Sleep(100);
                lcMeter.DisCharge(spLc);
                Thread.Sleep(100);

                double realVoltage = Convert.ToDouble(lcMeter.GetVoltage(spLc));//获取真实电压
                if (realVoltage > 2)
                {
                    lcMeter.DisCharge(spLc);
                    int dischargeCount = 0;
                    double realVoltage1 = Convert.ToDouble(lcMeter.GetVoltage(spLc));
                    while (true)
                    {
                        realVoltage = Convert.ToDouble(lcMeter.GetVoltage(spLc));
                        if (realVoltage1 > 1 && realVoltage - realVoltage1 > 1)
                        {
                            dischargeCount++;
                            ElectricViewModels.ForEach(m => m.RealVoltage = realVoltage);
                            if (dischargeCount >= 3)
                            {
                                lcMeter.DisCharge(spLc);
                                dischargeCount = 0;
                            }
                        }
                        else
                        {
                            ElectricViewModels.ForEach(m => m.RealVoltage = 0);
                            break;
                        }
                        Thread.Sleep(500);
                        if (s.Elapsed.TotalSeconds > 30) break;
                    }
                }
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
                sbComMessage.AppendLine("放电异常：" + ex.Message);
            }
        }

        void UpdateStatusLabel(string msg)
        {
            lblStatus.Text = msg;
        }

        /// <summary>
        /// 设置检测界面的默认检测项目
        /// </summary>
        public override void SetTestItem(string testItem) {
            _TestParams.TestItem = testItem;
            if (Version.StartsWith("2")) _TestParams.LcChargeTime = 120;
            BindingControls();
        }

        void SetControlsEnable(bool isTestting)
        {
            Grid.ReadOnly = !isTestting;
            btnTest.Enabled = isTestting;
            btnStop.Enabled = !isTestting;

            cboTestItem.Enabled = isTestting;
            cboCDFreq.Enabled = isTestting;
            cboZRFreq.Enabled = isTestting;
            txtLcrTestDelay.ReadOnly = !isTestting;

            txtVoltage.ReadOnly = !isTestting;
            txtChargeTime.ReadOnly = !isTestting;
            txtDischargeTime.ReadOnly = !isTestting;
            txtLcTestDelay.ReadOnly = !isTestting;
            cboLcLevel.Enabled = isTestting;
            numQty.ReadOnly = isTestting;

            if (cboTestItem.Tag == "LC") cboTestItem.Enabled = false;
        }
        #endregion

        #region 事件
        private void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                if (_TestWorker.IsBusy)
                {
                    QMessageBox.Show("系統忙碌中，請稍後再試...", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                lblStatus.Focus();

                if (cboTestItem.SelectedIndex == -1)
                {
                    QMessageBox.Show("請選擇測試項目", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    cboTestItem.Focus();
                    return;
                }

                if (_TestParams.TestItem.Contains("CD") 
                    && (cboCDFreq.SelectedIndex == -1 || string.IsNullOrWhiteSpace(_TestParams.CDFreq))
                    )
                {
                    QMessageBox.Show("請選擇CD頻率", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    cboCDFreq.Focus();
                    return;
                }

                if ((_TestParams.TestItem.Contains("R") || _TestParams.TestItem.Contains("Z")) 
                    && (string.IsNullOrWhiteSpace(_TestParams.ZRFreq) || cboZRFreq.SelectedIndex == -1)
    )
                {
                    QMessageBox.Show("請選擇ZR頻率", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    cboZRFreq.Focus();
                    return;
                }

                StartSerialPort();
                Thread.Sleep(100);

                if (Grid.Columns[Grid.CurrentCell.ColumnIndex] == ColLc2)
                    _TestParams.IsLC2 = true;
                else
                    _TestParams.IsLC2 = false;

                if (Grid.Columns[Grid.CurrentCell.ColumnIndex] == ColZ2)
                    _TestParams.IsZ2 = true;
                else
                    _TestParams.IsZ2 = false;

                if (Grid.Columns[Grid.CurrentCell.ColumnIndex] == ColEsr2)
                    _TestParams.IsEsr2 = true;
                else
                    _TestParams.IsEsr2 = false;

                if ((_TestParams.TestItem.Contains("LC") || _TestParams.IsLC2))
                {
                    if(QMessageBox.Show(string.Format("当前充电电压为 {0} ,请确认是否测试",_TestParams.LcVoltage.ToString())
                        , "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
                        == DialogResult.Cancel)
                    return;
                }
                else
                {
                    if (QMessageBox.Show("即将进行测试，请确认"
                        , "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
                        == DialogResult.Cancel)
                        return;
                }

                SetControlsEnable(false);
                isTestting = true;
                _TestParams.MaxTestVoltage = 0;
                _TestWorker.RunWorkerAsync();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                QMessageBox.Show(ex.Message, "異常0060", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            try
            {
                if (QMessageBox.Show("即將終止測試，請確認"
                    , "請確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1)
                    == DialogResult.Cancel)
                    return;
                if (_TestWorker != null && !_TestWorker.CancellationPending)
                    _TestWorker.CancelAsync();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        void ShowBoxMessage(string msg)
        {
            sbComMessage.AppendLine(msg);
        }

        //grid 绘制行号
        private void Grid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Common.DataGridViewSet.RowPostPaint(sender, e);
        }
        //关闭程序
        private void FormLCR1601_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                IsClosing = true;
                if (isTestting && (_TestStatus == TestStatus.LC測試中 || _TestStatus == TestStatus.充電中))
                {
                    DisCharge();
                }

                if (_TestWorker != null && _TestWorker.IsBusy)
                {
                    QMessageBox.Show("正在测试中，请等待测试完成后再关闭窗口！");
                    e.Cancel = true;
                    return;
                }

                if (spBox.IsOpen) try { spBox.Close(); } catch (Exception ex) { Logger.LogError(ex); }
                Thread.Sleep(100);
                if (spLc.IsOpen) try { spLc.Close(); } catch (Exception ex) { Logger.LogError(ex); }
                Thread.Sleep(100);
                if (spLc10.IsOpen) try { spLc10.Close(); } catch (Exception ex) { Logger.LogError(ex); }
                Thread.Sleep(100);
                if (spLcr.IsOpen) try { spLcr.Close(); } catch (Exception ex) { Logger.LogError(ex); }
                Thread.Sleep(200);

                Application.DoEvents();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                QMessageBox.ShowException(ex);
            }

            try
            {
                Grid.EndEdit();
                if(parentForm != null)
                {
                    var v = parentForm.GetType().GetMethod("RefreshTestGrid");
                    if (v != null && v.GetParameters().Length == 2)
                    {
                        v.Invoke(parentForm, new object[] { ElectricViewModels, IsDoubleTest });
                        Thread.Sleep(2000);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                QMessageBox.ShowException(ex);
            }      
        }

        private string strData = "";

        //监听LCR
        private void btnMonitor_Click(object sender, EventArgs e)
        {
            try
            {                
                if (isMonitor == true) //监听否
                {
                    isMonitor = false;
                    btnMonitor.ForeColor = Color.Black;
                    btnMonitor.Text = "打开LCR仪器(&L)";
                    this.timerLcr.Enabled = false;
                    Thread.Sleep(300);
                    COMClose();                                        
                }
                else
                {
                    isMonitor = true;
                    btnMonitor.ForeColor = Color.Red;
                    btnMonitor.Text = "请测试！(&L)";                    
                    isListening = false;
                    StartSerialPort();
                    btnTest.Focus();
                }
            }
            catch (Exception ex)
            {

                Logger.LogError(ex);
                //QMessageBox.Show("未能成功开启对LCR的监听");
            }
            finally
            {
                #if DEBUG
                //this.timerLcr.Enabled = true;
                #endif
            }
        }


        //检测项目选择关闭后定位到保存按钮
        private void cbTestItem_SelectionChangeCommitted(object sender, EventArgs e)
        {
            this.btnTest.Focus();
        }

        //设置
        private void btSet_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.spLcr.IsOpen && !_TestParams.IsLcOnly)
                {
                    string testItem = FormCommon.GetDataTableComboBoxValue(cboTestItem); //GetTestItem();
                    string freq = FormCommon.GetDataTableComboBoxValue(cboCDFreq);
                    string freq2 = FormCommon.GetDataTableComboBoxValue(cboZRFreq);
                    lcrMeter.SetFreq(spLcr, freq, freq, testItem); 
                }
            }
           catch(Exception ex)
            {
                Logger.LogError(ex);
                QMessageBox.Show(ex.Message,"異常S0062", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

#endregion

#region 方法
        //初始化combo
        private void InitCombo()
        {
            DataTable dt = MachineFactory.GetLcrFrequencyTable();
            cboCDFreq.DisplayMember = dt.Columns[1].ColumnName;
            cboCDFreq.ValueMember = dt.Columns[0].ColumnName;
            cboCDFreq.DataSource = dt;
            cboCDFreq.SelectedIndex = 0;

            dt = dt.Copy();
            cboZRFreq.DisplayMember = dt.Columns[1].ColumnName;
            cboZRFreq.ValueMember = dt.Columns[0].ColumnName;
            cboZRFreq.DataSource = dt;
            if(dt.Rows.Count>1) cboZRFreq.SelectedIndex = 1;

            dt = MachineFactory.GetAutoTestItemTable();
            cboTestItem.DisplayMember = dt.Columns[1].ColumnName;
            cboTestItem.ValueMember = dt.Columns[0].ColumnName;
            cboTestItem.DataSource = dt;

            dt = MachineFactory.GetLcLevelTable();
            cboLcLevel.DisplayMember = dt.Columns[1].ColumnName;
            cboLcLevel.ValueMember = dt.Columns[0].ColumnName;
            cboLcLevel.DataSource = dt;
        }

        //初始化gird
        private void BindingControls()
        {
            try
            {
                this.Grid.DataSource = new BindingList<ElectricViewModel>(ElectricViewModels);

                #region 
                cboTestItem.DataBindings.Clear();
                cboCDFreq.DataBindings.Clear();
                cboZRFreq.DataBindings.Clear();
                txtLcrTestDelay.DataBindings.Clear();
                txtVoltage.DataBindings.Clear();
                txtChargeTime.DataBindings.Clear();
                txtDischargeTime.DataBindings.Clear();
                txtLcTestDelay.DataBindings.Clear();
                cboLcLevel.DataBindings.Clear();
                numQty.DataBindings.Clear();

                cboTestItem.DataBindings.Add("SelectedValue", _TestParams, "TestItem");
                cboCDFreq.DataBindings.Add("SelectedValue", _TestParams, "CDFreq");
                cboZRFreq.DataBindings.Add("SelectedValue", _TestParams, "ZRFreq");
                txtLcrTestDelay.DataBindings.Add("Text", _TestParams, "LcrTestDelay");
                txtVoltage.DataBindings.Add("Text", _TestParams, "LcVoltage");
                txtChargeTime.DataBindings.Add("Text", _TestParams, "LcChargeTime");
                txtDischargeTime.DataBindings.Add("Text", _TestParams, "LcDischargeTime");
                txtLcTestDelay.DataBindings.Add("Text", _TestParams, "LcTestDelay");
                cboLcLevel.DataBindings.Add("SelectedValue", _TestParams, "LcLevel");
                numQty.DataBindings.Add("Value", _TestParams, "Qty");
            }
            catch(Exception ex)
            {
                QMessageBox.Show(ex.Message,"S0061",MessageBoxButtons.OK,MessageBoxIcon.Error);
                Logger.LogError(ex);
            }
            #endregion
        }

        //开始监听
        public void StartSerialPort()
        {
            try
            {
                if (!spLcr.IsOpen)
                {
                    try
                    {
                        if (!_TestParams.IsLcOnly)
                        {
                            try
                            {
                                spLcr.Open();
                                sbComMessage.AppendLine(spLcr.PortName);
                                sbComMessage.AppendLine(spLcr.IsOpen.ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex);
                                sbComMessage.AppendLine("容量表串口打开异常：" + ex.Message);
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        Logger.LogError(ex);
                    }
                }

                if (!spLc.IsOpen)
                {
                    try
                    {
                        if (IsAllAuto || _TestParams.IsLcOnly)
                        {
                            try
                            {
                                spLc.Open();
                                sbComMessage.AppendLine(spLc.PortName);
                                sbComMessage.AppendLine(spLc.IsOpen.ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex);
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        Logger.LogError(ex);
                        sbComMessage.AppendLine("LC串口打开异常：" + ex.Message);
                    }
                }
                
                if (!spLc10.IsOpen)
                {
                    try
                    {
                        if (IsAllAuto || _TestParams.IsLcOnly)
                        {
                            try
                            {
                                spLc10.Open();
                                sbComMessage.AppendLine(spLc10.PortName);
                                sbComMessage.AppendLine(spLc10.IsOpen.ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex);
                                sbComMessage.AppendLine("10通道LC串口打开异常：" + ex.Message);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex);
                    }
                }
                
                if (!spBox.IsOpen)
                {
                    try
                    {
                        if (IsAllAuto || _TestParams.IsLcOnly)
                        {
                            try
                            {
                                spBox.Open();
                                sbComMessage.AppendLine(spBox.PortName);
                                sbComMessage.AppendLine(spBox.IsOpen.ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.LogError(ex);
                                sbComMessage.AppendLine("通道盒子串口打开异常：" + ex.Message);
                            }
                        }
                    }
                    catch(Exception ex)
                    {
                        Logger.LogError(ex);
                    }
                }
            }
            catch(Exception ex)
            {
                //QMessageBox.Show(ex.Message, "異常S0067", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Logger.LogError(ex);
                sbComMessage.AppendLine("串口打开异常：" + ex.Message);
            }
        }

        //獲取端口和波特率
        private void getPortBuad()
        {
            try
            {
                Settings.GetPortBuad(spLcr, Settings.MachineType.LCR);
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }

            try
            {
                Settings.GetPortBuad(spLc, Settings.MachineType.LC);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }

            try
            {
                Settings.GetPortBuad(spLc10, Settings.MachineType.Lc10);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }

            try
            {
                Settings.GetPortBuad(spBox, Settings.MachineType.Box);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

#endregion

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns></returns>
        private bool COMClose()
        {
            try
            {
                if (spLcr.IsOpen)
                {                    
                    while (isListening) //如果com口还未退出则等待com口线程结束
                        Application.DoEvents();

                    timerLcr.Enabled = false;
                    timerLc.Enabled = false;
                    timerLc10.Enabled = false;
                    timerStatus.Enabled = false;

                    Thread.Sleep(200);
                    try { spLcr.Close(); } catch { }
                    Thread.Sleep(50);
                    try { spLc.Close(); } catch { }
                    Thread.Sleep(50);
                    try { spBox.Close(); } catch { }
                    Thread.Sleep(50);
                    try { spLc10.Close(); } catch { }
                }                 
                return true;
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex);
                return false;
            }
        }

        private void cboFreq_SelectedIndexChanged(object sender, EventArgs e)
        {
            btSet_Click(null, null); //设置检测频率
            btnTest.Focus();
        }

        public void RefreshGrid()
        {
            Grid.Refresh();
        }

        private void Grid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            //string value = e.FormattedValue.ToString();
            //double value1 = 0m;
            //if (!double.TryParse(value,out value1))
            //{
            //    e.Cancel = true;
            //}
        }

        private void Grid_SelectionChanged(object sender, EventArgs e)
        {
            if (!isTestting)
            {
                if (Grid.CurrentCell != null && Grid.CurrentCell.RowIndex < Grid.Rows.Count - 1)
                    _CurrentRowIndex = Grid.CurrentCell.RowIndex;
                else if (Grid.CurrentCell == null)
                    _CurrentRowIndex = 0;
            }
        }

        #region 右鍵菜單
        private void tsmClear_Click(object sender, EventArgs e)
        {
            if (Grid.CurrentCell != null) Grid.CurrentCell.Value = null;
        }

        private void tsmClearColumn_Click(object sender, EventArgs e)
        {
            try
            {
                if (QMessageBox.Show("即將清除當前列數據，請確認", "請確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
    == DialogResult.Cancel)
                    return;

                if (Grid.CurrentCell != null)
                {
                    int colmnIndex = Grid.CurrentCell.ColumnIndex;
                    for (int i = 0; i < Grid.Rows.Count; i++)
                    {
                        Grid.Rows[i].Cells[colmnIndex].Value = null;
                    }
                }
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
                //QMessageBox.Show(ex.Message, "異常S0035", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            //清除行
            //if (Grid.CurrentRow != null)
            //{
            //    var v = Grid.CurrentRow.DataBoundItem as ElectricViewModel;
            //    if(v != null)
            //    {
            //        v.Clear();
            //        this.Grid.Refresh();
            //    }
            //}
        }

        private void tsmClearAll_Click(object sender, EventArgs e)
        {
            try
            {
                if (QMessageBox.Show("即將清除網格所有數據，請確認", "請確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
                    == DialogResult.Cancel)
                    return;

                if (ElectricViewModels != null && ElectricViewModels.Count > 0)
                {
                    foreach (ElectricViewModel v in ElectricViewModels)
                    {
                        v.Clear();
                    }
                    this.Grid.Refresh();
                }
            }
            catch (Exception ex)

            {
                Logger.LogError(ex);
                //QMessageBox.Show(ex.Message, "異常S0035", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion 右鍵菜單


        bool isESCcancel = false;
        private void Grid_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            try
            {
                if (Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Double)
                    || Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].ValueType == typeof(Decimal))
                {
                    Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = 0;
                    e.Cancel = true;
                    SendKeys.Send("{ESC}");
                    isESCcancel = true;
                }
            }
            catch(Exception ex)
            {

            }
        }

        private void Grid_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space)
                e.SuppressKeyPress = false;
        }

        //显示调试信息
        private void tsmDebugMsg_Click(object sender, EventArgs e)
        {
            try
            {
                formMutilMsgBox = new FormMutilMsgBox(string.Empty, string.Empty, sbComMessage.ToString());
                formMutilMsgBox.Show();
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        //显示状态label
        private void timerStatus_Tick(object sender, EventArgs e)
        {
            try
            {
                return;
                Action<string> action = UpdateStatusLabel;
                int delay = _TestParams.LcChargeTime
                    - (int)stopwatch.Elapsed.TotalSeconds;
                if (delay < 0) delay = 0;
                this.Invoke(action, delay.ToString() + Enum.GetName(_TestStatus.GetType(), _TestStatus));
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        private void cboLcLevel_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                lblStatus.Focus();
                if (string.IsNullOrWhiteSpace(_TestParams.LcLevel)) return;
                if (!spLc.IsOpen) StartSerialPort();
                lcMeter.SetLeak(spLc,_TestParams.LcLevel);
                cboLcLevel.Focus();
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        public void SetZ2Visible(bool isVisible)
        {
            ColZ2.Visible = isVisible;
        }
        public void SetLc2Visible(bool isVisible)
        {
            ColLc2.Visible = isVisible;
        }

        public void SetEsr2Visible(bool isVisible)
        {
            ColEsr2.Visible = isVisible;
        }

        public void SetLcOnly()
        {
            try
            {
                foreach(DataGridViewColumn c in Grid.Columns)
                {
                    if(c != ColLc && c != ColLc2 && c != ColRealVoltage)
                    {
                        c.Visible = false;
                    }
                }

                DataTable testItemTable = cboTestItem.DataSource as DataTable;
                _TestParams.TestItem = "LC";
                cboTestItem.Enabled = false;
                cboTestItem.Tag = "LC";
                _TestParams.IsLcOnly = true;
                if (spLcr.IsOpen) spLcr.Close();
                Thread.Sleep(200);
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        public void SetLcrOnly()
        {
            try
            {
                foreach (DataGridViewColumn c in Grid.Columns)
                {
                    if (c == ColLc || c == ColLc2 || c == ColRealVoltage)
                    {
                        c.Visible = false;

                    }
                }

                DataTable testItemTable = cboTestItem.DataSource as DataTable;
                List<DataRow> delRows = new List<DataRow>();
                foreach (DataRow r in testItemTable.Rows)
                {
                    if (r["Value"].ToString().Contains( "LC"))
                    {
                        delRows.Add(r);
                    }
                }

                foreach (DataRow r in delRows)
                {
                    testItemTable.Rows.Remove(r);
                }

                _TestParams.IsLcrOnly = true;
                if (spLc.IsOpen) spLc.Close();
                if (spLc10.IsOpen) spLc10.Close();
                if (spBox.IsOpen) spBox.Close();
                Thread.Sleep(200);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        private void Grid_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                ElectricViewModel view = this.Grid.CurrentRow.DataBoundItem as ElectricViewModel;
                if (view == null) return;

                double value = 0;
                double.TryParse(Grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(), out value);

                DataGridViewColumn column = this.Grid.Columns[e.ColumnIndex];
                if (column == ColLc)
                {
                    view.LCisValid =
                                IsValid(ItemCode.LC, value, view);
                    //FirstStandardView.IsValid(ItemCode.LC, value);
                }
                else if (column == ColLc2)
                {
                    view.LC2isValid = IsValid(ItemCode.LC2, value, view);
                    //FirstStandardView.IsValid(ItemCode.LC2, value);
                }
                else if (column == ColCap)
                {
                    view.CAPisValid = IsValid(ItemCode.CAP, value, view);
                    //FirstStandardView.IsValid(ItemCode.CAP, value);
                }
                else if (column == ColDf)
                {
                    view.DFisValid = IsValid(ItemCode.DF, value, view);
                    //FirstStandardView.IsValid(ItemCode.DF, value);
                }
                else if (column == ColZ)
                {
                    view.ZisValid = IsValid(ItemCode.Z, value, view);
                    //FirstStandardView.IsValid(ItemCode.Z, value);
                }
                else if (column == ColZ)
                {
                    view.Z2isValid = IsValid(ItemCode.Z2, value, view);
                    //FirstStandardView.IsValid(ItemCode.Z2, value);
                }
                else if (column == ColEsr)
                {
                    view.ESRisValid = IsValid(ItemCode.ESR, value, view);
                    //FirstStandardView.IsValid(ItemCode.ESR, value);
                }
                else if (column == ColEsr2)
                {
                    view.ESR2isValid = IsValid(ItemCode.ESR2, value, view);
                    //FirstStandardView.IsValid(ItemCode.ESR2, value);
                }

                this.Grid.Refresh();
            }
            catch(Exception ex)
            {
                Logger.LogError(ex);
            }
        }

        private void Grid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (isESCcancel)
                {
                    isESCcancel = false;
                    if (e.RowIndex < Grid.Rows.Count - 1)
                    {

                        Grid.CurrentCell = Grid.Rows[e.RowIndex + 1].Cells[e.ColumnIndex];
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        private void tsmExport_Click(object sender, EventArgs e)
        {
            try
            {
                string fileName = NPOIHelper.DataGridViewToExcel(
                    "autotest_" + DateTime.Now.ToString("yyyyMMddHHmmss")
                    , Grid
                    , Grid.DefaultCellStyle.Font.Name
                    , Convert.ToInt16(Grid.DefaultCellStyle.Font.Size)
                    , true, string.Empty);

                Process.Start(fileName);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                QMessageBox.Show(ex.Message, "异常902", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
